package ipebg.mzk.provider.system.service.impl;

import ipebg.mzk.common.core.dao.IRedisDao;
import ipebg.mzk.common.util.DateTool;
import ipebg.mzk.common.util.StringTool;
import ipebg.mzk.facade.config.Config;
import ipebg.mzk.facade.entity.LogMongo;
import ipebg.mzk.facade.entity.MsAccessCountRecord;
import ipebg.mzk.facade.enums.LogLevel;
import ipebg.mzk.facade.enums.WebAccessType;
import ipebg.mzk.facade.system.service.LogService;
import ipebg.mzk.facade.system.service.MsAccessCountRecordService;
import ipebg.mzk.provider.system.dao.MsAccessCountRecordDao;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("msAccessCountRecordServiceImpl")
public class MsAccessCountRecordServiceImpl implements MsAccessCountRecordService {
	private static Log log = LogFactory.getLog(MsAccessCountRecordServiceImpl.class);

	@Resource(name = "msAccessCountRecordDao")
	MsAccessCountRecordDao msAccessCountRecordDao;

	@Resource(name = "redisDao")
	IRedisDao redisDao;

	@Resource(name = "logServiceImpl")
	private LogService logServiceImpl;

	@Override
	public Long OnlineLoginUserCount() throws Exception {
		Long lResult = 0L;
		try {
			double minScore = 0, maxScore = 0;
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.MINUTE, -30);
			maxScore = Calendar.getInstance().getTimeInMillis();
			minScore = calendar.getTimeInMillis();
			lResult = redisDao.zcount(Config.REDIS_KEY_ONLINE_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), minScore, maxScore);

		} catch (Exception e) {
			throw e;
		}
		return lResult;
	}

	@Override
	public Long LoginCountByDay(Date date) throws Exception {
		double minScore = 0, maxScore = 0;
		maxScore = Calendar.getInstance().getTimeInMillis();
		Calendar calendar = Calendar.getInstance();
		calendar.set(calendar.YEAR, calendar.MONTH, calendar.DATE, 0, 0, 0);
		minScore = calendar.getTimeInMillis();
		Long lResult = redisDao.zcount(Config.REDIS_KEY_ONLINE_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), minScore, maxScore);
		return lResult;
	}

	@Override
	public Long VisitCountByDay(Date date) throws Exception {
		double minScore = 0, maxScore = 0;
		maxScore = Calendar.getInstance().getTimeInMillis();
		Calendar calendar = Calendar.getInstance();
		calendar.set(calendar.YEAR, calendar.MONTH, calendar.DATE, 0, 0, 0);
		minScore = calendar.getTimeInMillis();
		Long lResult = redisDao.zcount(Config.REDIS_KEY_VISIT_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), minScore, maxScore);
		return lResult;
	}

	@Override
	public Set<String> GetOnlineUserList() {
		double minScore = 0, maxScore = 0;
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, Config.SESSION_TIMEOUT);
		maxScore = Calendar.getInstance().getTimeInMillis();
		minScore = calendar.getTimeInMillis();
		Set<String> result = redisDao.zrangeByScore(Config.REDIS_KEY_ONLINE_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), minScore, maxScore);
		return result;
	}

	@Override
	public void AddOnlineUser(String userCode) {
		double timeStart = 0;
		Calendar calendar = Calendar.getInstance();
		timeStart = calendar.getTimeInMillis();
		// System.out.println(timeStart);
		redisDao.zadd(Config.REDIS_KEY_ONLINE_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), timeStart, userCode);
		/*
		 * Set<Tuple>
		 * pageString=redisClientServiceImpl.zrangeByScoreWithScores("myzset",
		 * 0.0, 31.0,2,10); Iterator it = pageString.iterator();
		 * while(it.hasNext()){ Tuple tuple=(Tuple) it.next();
		 * System.out.println(tuple.getScore()+ " is score,"+
		 * tuple.getElement()+" is value"); }
		 */
		// Long lCount = redisDao.zremrangeByScore("myzset", 10, 20);
		// System.out.println("remvoed count"+lCount);
	}

	@Override
	public void AddVisitUser(String sessionId) throws Exception {
		try {
			double timeStart = 0;
			Calendar calendar = Calendar.getInstance();
			timeStart = calendar.getTimeInMillis();
			// System.out.println(timeStart);
			redisDao.zadd(Config.REDIS_KEY_VISIT_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), timeStart, sessionId);
		} catch (Exception e) {
			throw e;
		}
	}

	@Override
	public void RemoveVisitUser(String sessionId) throws Exception {
		try {
			redisDao.zrem(Config.REDIS_KEY_VISIT_USER+StringTool.GetCurrentSystemDate("yyyyMMdd"), sessionId);// (sessionId);
		} catch (Exception e) {
			throw e;
		}
	}

	@Transactional
	@Override
	public void Persistent2DB() throws Exception {
		try {
			Long countLoginToday = LoginCountByDay(new Date());
			Long countVisitToday = VisitCountByDay(new Date());

			/* 更新Login數據 */
			MsAccessCountRecord record = findMsAccessCountRecordByDate(new Date(), WebAccessType.LOGIN_TYPE.toString());
			if (record == null) {
				record = new MsAccessCountRecord();
				record.setRecordId(UUID.randomUUID().toString());
				record.setRecordDay(DateTool.toShortDate(new Date()));
				record.setRecordType(WebAccessType.LOGIN_TYPE.toString());
			}

			record.setAccessCount(Integer.valueOf(String.valueOf(countLoginToday)));
			record.setUpdateDatetime(new Date());
			msAccessCountRecordDao.saveOrUpdate(record);

			/* 更新Visit數據 */
			record = null;
			record = findMsAccessCountRecordByDate(new Date(), WebAccessType.VISIT_TYPE.toString());
			if (record == null) {
				record = new MsAccessCountRecord();
				record.setRecordId(UUID.randomUUID().toString());
				record.setRecordDay(DateTool.toShortDate(new Date()));
				record.setRecordType(WebAccessType.VISIT_TYPE.toString());
			}
			record.setAccessCount(Integer.valueOf(String.valueOf(countVisitToday)));
			record.setUpdateDatetime(new Date());
			msAccessCountRecordDao.saveOrUpdate(record);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw e;
		}
	}

	@Override
	public void update(MsAccessCountRecord record) throws Exception {
		try {
			msAccessCountRecordDao.saveOrUpdate(record);
		} catch (Exception e) {
			throw e;
		}
	}

	@Override
	public MsAccessCountRecord findMsAccessCountRecordByDate(Date recordDay, String recordType) throws Exception {
		MsAccessCountRecord record = null;
		try {
			String sRecordDay = DateTool.toShortDate(recordDay);
			List<MsAccessCountRecord> list = msAccessCountRecordDao.findByProperty(MsAccessCountRecord.class, new String[] { "recordDay", "recordType" }, new Object[] { sRecordDay, recordType });// findByExample(record,
																																																	// null);
			if (list != null && list.size() > 0) {
				record = list.get(0);
			}
		} catch (Exception e) {
			throw e;
		}
		return record;
	}

	@Override
	@Transactional
	public Long findAccessCountByDays(String beginDay, String endDay, String accessType) throws Exception {
		Long count = 0L;
		try {
			count = msAccessCountRecordDao.findAccessCountByDays(beginDay, endDay, accessType);
		} catch (Exception e) {
			throw e;
		}
		return count;
	}

}
